Skip to content

0.1 + 0.2 !== 0.3,如何解决上面说的精确度丢失问题

计算机中用二进制来存储小数,而大部分小数转成二进制之后都是无限循环的值,因此存在取舍问题,也就是精度丢失 64位双精度浮点位 1 符号位 11 指数位 52 有效数字

怎么解决

  • toFixed
  • 解决小数问题,但是带来一个新问题,大数之和
js
function add(num1, num2) {
  const num1Digits = (num1.toString().split(".")[1] || "").length; // 小数点后面有几位
  const num2Digits = (num2.toString().split(".")[1] || "").length;

  // 小数点后面有几位选择最大值 例如2,则 baseNum = 10 * 10 * 10
  const baseNum = Math.pow(10, Math.max(num1Digits, num2Digits));

  return (num1 * baseNum + num2 * baseNum) / baseNum;
}
add(0.1, 0.2);

大数之和

js
import Decimal from 'decimal.js';
const value = new Decimal(uid)

判断两个小数是否相等

js
Number.EPSILON = (function () {
  //解决兼容性问题
  return Number.EPSILON ? Number.EPSILON : Math.pow(2, -52);
})();

function numbersequal(a, b) {
  return Math.abs(a - b) < Number.EPSILON;
}

//接下来再判断
var a = 0.1 + 0.2,
  b = 0.3;
console.log(numbersequal(a, b)); //这里就为true了

Number 最大数

  • 安全数字范围 15 位以下

  • JavaScript 并不能表示任意位的整数,最大的整数是 Number.MAX_SAFE_INTEGER(9007199254740991),最小的整数是 Number.MIN_SAFE_INTEGER(-9007199254740991)

  • 特别注意,很多 ID 是超出这个范围的,所以 ID 最好是用 string,当 ID 超出 15 位数的话,就肯定要用字符串类型了。

  • 超出会失准

js
var a = 9007199254740995;
a; // 9007199254740996

在 MIT 许可下发布